#include "common.h"
#include "syscall.h"
#include "fs.h"

extern int mm_brk(uint32_t new_brk);

uintptr_t sys_write(int fd, const void* buf, size_t count) {
  uintptr_t i = 0;
  if ((fd != 1 && fd != 2) || buf == NULL || count == 0) return i;
  // 将缓冲区内容逐字节输出到串口
  char* cbuf = (char*)buf;
  for (; i < count; i++) {
      _putc(cbuf[i]);
     //Log("sys_write fd：%d", fd);
  }
  return i;
}

_RegSet* do_syscall(_RegSet *r) {
  uintptr_t a[4];
  a[0] = SYSCALL_ARG1(r);
  a[1] = SYSCALL_ARG2(r);
  a[2] = SYSCALL_ARG3(r);
  a[3] = SYSCALL_ARG4(r);

  switch (a[0]) {
    case SYS_none:
    SYSCALL_ARG1(r) = 1;
      break;
    case SYS_exit:
      _halt(a[1]);
      break;
    case SYS_brk:
    SYSCALL_ARG1(r) = mm_brk(a[1]);
      break;
    case SYS_open:
      //Log("SYS_open called, pathname:%s", (char*)a[1]);
      SYSCALL_ARG1(r) = fs_open((char*)a[1], a[2], a[3]);
      break;

    case SYS_read:
      //Log("SYS_read called, fd:%d, len:%d", a[1], a[3]);
      SYSCALL_ARG1(r) = fs_read(a[1], (void*)a[2], a[3]);
      break;

    case SYS_write:
      //Log("SYS_write called, fd:%d, len:%d", a[1], a[3]);
      SYSCALL_ARG1(r) = fs_write(a[1], (void*)a[2], a[3]);
      break;

    case SYS_close:
      SYSCALL_ARG1(r) = fs_close(a[1]);
      break;

    case SYS_lseek:
      //Log("SYS_lseek called, fd:%d, offset:%d, whence:%d", a[1], (off_t)a[2], a[3]);
      SYSCALL_ARG1(r) = fs_lseek(a[1], (off_t)a[2], a[3]);
      break;

    default: panic("Unhandled syscall ID = %d", a[0]);
  }
  return r;
}
